/**
 * @auther jiagnqifan
 * @since 2016-04-06
 */
var fs = require('fs');
var path = require('path');

function travelSeq(dir, callback, dirCallback, finish) {
    fs.readdir(dir, function (err, files) {
        (function next(i) {
            if (i < files.length) {

            	var name = files[i];
                var pathname = path.join(dir, name);

                fs.stat(pathname, function (err, stats) {
                    if (stats.isDirectory()) {
                    	dirCallback(name, function(){
                    		travel(pathname,
                    		function(n, next){
                    			callback(path.join(name,n), next);
                    		}, function(n, next){
                    			dirCallback(path.join(name,n), next);
                    		}, function () {
	                            next(i + 1);
	                        });
                    	});

                    } else {
                        callback(name, function () {
                            next(i + 1);
                        });
                    }
                });
            } else {
                finish && finish();
            }
        }(0));
    });
}


var CountDown = function(name, count, callback){
  var total = count;
	this.down = function(){
    // console.log('countdown:[]'+name+"] = " + (count-1)+"/"+total);
		if(!--count) callback();
	}
  if(total<1){
    callback();
  }
}

function travel(dir, callback, dirCallback, finish) {
    fs.readdir(dir, function (err, files) {
      if(err){
        console.log(err);
      }

    	var countDown = new CountDown(dir, files.length, function(){
        // console.log('finish:'+dir);
    		finish && finish();
    	});

    	files.forEach(function(name){
    		var pathname = path.join(dir, name);

            fs.stat(pathname, function (err, stats) {
                if (stats.isDirectory()) {
                	dirCallback(name, function () {
                       travel(pathname,
                       	function(n,next){
                       		callback(path.join(name,n), next);
                       	},
                       	function(n,next){
                       		dirCallback(path.join(name,n), next);
                       	},
                       	function () {
	                        countDown.down();
	                    });
                    });
                } else {
                    callback(name, function () {
                        countDown.down();
                    });
                }
            });
    	});
    });
}

//并行复制
exports.copy = function(options, callback){
  var src = options.src;
  var dest = options.dest;
  var filter = options.filter

	fs.exists(dest, function(exist){
		if(exist){
			doCopy();
		} else {
			fs.mkdir(dest,doCopy);
		}
	});

	function doCopy(){
		travel(src, function(name, callback){
      if(filter && !filter(path.join(src,name))){
        callback();
      }else {
        fs.createReadStream(path.join(src,name)).pipe(fs.createWriteStream(path.join(dest, name))).on('finish',function(){
  				callback();
  			});
      }

		}, function(name, callback){
      if(filter && !filter(path.join(src,name))){
        callback();
      } else {
        fs.mkdir(path.join(dest,name), function(){
          callback();
        });
      }
		},callback);
	}

};

//串行复制
exports.copySeq = function(src, dest, callback){
	fs.exists(dest, function(exist){
		if(exist){
			doCopy();
		} else {
			fs.mkdir(dest,doCopy);
		}
	});

	function doCopy(){
		travelSeq(src, function(name, next){
			fs.createReadStream(path.join(src, name)).pipe(fs.createWriteStream(path.join(dest,name))).on('finish', function(){
				next();
			});
		}, function(name, next){
			fs.mkdir(path.join(dest,name), function(){
				next();
			});
		},callback);
	}

};
